/*
 * @Author: Flying
 * @Date: 2022-07-24 17:00:00
 * @LastEditors: Flying
 * @LastEditTime: 2022-07-24 22:47:30
 * @Description: 修改文件
 */
#include "sys_quick_win.h"

sys_quick_win::sys_quick_win(int start_x, int start_y, sys_quick_func_t func)
    : start_x(start_x), start_y(start_y), end_x(start_x), end_y(start_y)
{
    this->is_show = false;

    // LV_LOG_USER("x %d,y %d", start_x, start_y);
    this->cont = lv_obj_create(lv_layer_sys());
    lv_obj_set_style_radius(this->cont, 0, 0);
    lv_obj_set_pos(this->cont, 0, 0);
    lv_obj_set_style_pad_all(this->cont, 0, 0);
    lv_obj_set_size(this->cont, lv_pct(100), lv_pct(100));
    lv_obj_set_style_opa(this->cont, LV_OPA_10, 0);
    lv_obj_set_style_bg_color(this->cont, lv_color_black(), 0);
    lv_obj_set_style_border_width(this->cont, 0, 0);

    lv_obj_add_event_cb(this->cont, sys_quick_win::exit_evnet_cb, LV_EVENT_CLICKED, this);

    LV_ASSERT(func);

    this->win = func(lv_layer_sys());
    lv_obj_set_pos(this->win, start_x, start_y);
    lv_obj_set_user_data(this->win, this);
    this->w = lv_obj_get_style_width(this->win, 0);
    this->h = lv_obj_get_style_height(this->win, 0);

    for (int i = 0; i < lv_obj_get_child_cnt(this->win); i++)
    {
        lv_obj_add_flag(lv_obj_get_child(this->win, i), LV_OBJ_FLAG_HIDDEN);
    }

    // this->win = lv_obj_create(this->cont);
    // lv_obj_set_style_bg_color(this->win, lv_color_black(), 0);
    // lv_obj_set_pos(this->win, start_x, start_y);
    // lv_obj_set_style_pad_all(this->win, 0, 0);
    // lv_obj_set_user_data(this->win, this);

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, this->win);
    lv_anim_set_exec_cb(&a, open_changer_anim_cb);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_in);
    lv_anim_set_values(&a, 0, 300);
    lv_anim_set_time(&a, 300);
    lv_anim_start(&a);

    this->calc_end_pos();
}

sys_quick_win::~sys_quick_win()
{
    lv_obj_del_async(this->cont);
    this->cont = NULL;
    lv_obj_del_async(this->win);
    this->win = NULL;
}

/**
 * @description: 替代delete，需要做动画
 * @return {*}
 */
void sys_quick_win::del_this()
{
    if (lv_anim_get(this->win, exit_changer_anim_cb))
    {
        return;
    }
    for (int i = 0; i < lv_obj_get_child_cnt(this->win); i++)
    {
        lv_obj_add_flag(lv_obj_get_child(this->win, i), LV_OBJ_FLAG_HIDDEN);
    }

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, this->win);
    lv_anim_set_exec_cb(&a, exit_changer_anim_cb);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
    lv_anim_set_values(&a, 0, 300);
    lv_anim_set_time(&a, 300);
    lv_anim_start(&a);
}

void sys_quick_win::exit_evnet_cb(lv_event_t *e)
{
    sys_quick_win *_this = (sys_quick_win *)lv_event_get_user_data(e);
    if (_this->is_show == false)
    {
        return;
    }

    _this->del_this();
}

/**
 * @description: 计算终点坐标
 * @return {*}
 */
void sys_quick_win::calc_end_pos()
{
    if (this->start_y + this->h < MY_UI_H_MAX)
    { //向下
        this->end_y = this->start_y;
        if (this->start_x + this->w < MY_UI_W_MAX)
        { //左边
            this->end_x = this->start_x;
            return;
        }

        if (this->start_x - this->w >= 0)
        { //右边
            this->end_x = this->start_x - this->w;
            return;
        }
    }

    if (this->start_y - this->h >= 0)
    { //向上
        this->end_y = this->start_y - this->h;

        if (this->start_x + this->w < MY_UI_W_MAX)
        { //左边
            this->end_x = this->start_x;
            return;
        }

        if (this->start_x - this->w >= 0)
        { //右边
            this->end_x = this->start_x - this->w;
            return;
        }
    }

    //其余情况居中，并预留退出空间
    this->w = this->w > MY_UI_W_MAX - 50 * MY_UI_W_ZOOM ? MY_UI_W_MAX - 50 * MY_UI_W_ZOOM : this->w;
    this->h = this->h > MY_UI_H_MAX - 50 * MY_UI_W_ZOOM ? MY_UI_H_MAX - 50 * MY_UI_H_ZOOM : this->h;
    this->end_x = (MY_UI_W_MAX - this->w) / 2;
    this->end_y = (MY_UI_H_MAX - this->h) / 2;
}

/**
 * @description: 动画轨迹
 * @param {void} *var
 * @param {int32_t} v
 * @return {*}
 */
void sys_quick_win::open_changer_anim_cb(void *var, int32_t v)
{
    lv_obj_t *obj = (lv_obj_t *)var;
    lv_coord_t w, h;
    lv_coord_t x, y;
    sys_quick_win *_this = (sys_quick_win *)lv_obj_get_user_data(obj);

    x = lv_map(v, 0, 300, _this->start_x, _this->end_x);
    y = lv_map(v, 0, 300, _this->start_y, _this->end_y);
    w = lv_map(v, 0, 300, 0, _this->w);
    h = lv_map(v, 0, 300, 0, _this->h);
    lv_obj_set_pos(obj, x, y);
    lv_obj_set_size(obj, w, h);
    if (v == 300)
    {
        _this->is_show = true;
        for (int i = 0; i < lv_obj_get_child_cnt(_this->win); i++)
        {
            lv_obj_clear_flag(lv_obj_get_child(_this->win, i), LV_OBJ_FLAG_HIDDEN);
        }
    }
}

/**
 * @description: 退出动画轨迹
 * @param {void} *var
 * @param {int32_t} v
 * @return {*}
 */
void sys_quick_win::exit_changer_anim_cb(void *var, int32_t v)
{
    lv_obj_t *obj = (lv_obj_t *)var;
    lv_coord_t w, h;
    lv_coord_t x, y;
    sys_quick_win *_this = (sys_quick_win *)lv_obj_get_user_data(obj);

    x = lv_map(v, 0, 300, _this->end_x, _this->start_x);
    y = lv_map(v, 0, 300, _this->end_y, _this->start_y);
    w = lv_map(v, 0, 300, _this->w, 0);
    h = lv_map(v, 0, 300, _this->h, 0);
    lv_obj_set_pos(obj, x, y);
    lv_obj_set_size(obj, w, h);
    if (v == 300)
    {
        delete _this;
    }
}